package com.zxd.service.impl;

import com.zxd.core.Constant;
import com.zxd.dao.RoleDao;
import com.zxd.dao.RoleModuleDao;
import com.zxd.dao.RoleRelationDao;
import com.zxd.entity.Module;
import com.zxd.entity.Role;
import com.zxd.entity.RoleModule;
import com.zxd.entity.vo.BaseVo;
import com.zxd.service.RoleService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * roleServiceImpl
 * Created by 奕恒 on 2017/2/20 21:54.
 */
@Service
public class RoleServiceImpl implements RoleService {

    @Autowired
    private RoleDao roleDao;

    @Autowired
    private RoleModuleDao roleModuleDao;

    @Autowired
    private RoleRelationDao roleRelationDao;

    @Override
    public List<Role> findAll() {
        return roleDao.findAll();
    }

    @Override
    public Page<Role> find(int pageNum, int pageSize) {
        return roleDao.findAll(new PageRequest(pageNum - 1, pageSize, Sort.Direction.DESC, "id"));
    }

    @Override
    public Page<Role> find(int pageNum) {
        return find(pageNum, Constant.PAGE_DEF_SIZE);
    }

    @Override
    public Role getById(int id) {
        return roleDao.findOne(id);
    }

    @Override
    public void deleteById(int id) {
        roleDao.delete(id);
    }

    @Override
    public Role create(Role role) {
        return roleDao.save(role);
    }

    @Override
    public Role update(Role role) {
        return roleDao.save(role);
    }

    @Override
    @Transactional
    public void deleteAll(int[] ids) {
        for (int id : ids) {
            deleteById(id);
        }
    }

    @Override
    public BaseVo getPowerData(final String keyWord, Integer pageNum, Integer pageSize) {
        List<Map<String, Object>> list = new ArrayList<>();
        Map<String, Object> map;

        List<Role> roleList = roleDao.findAll((root, query, cb) -> {
            Predicate result = null;
            List<Predicate> predicateList = new ArrayList<>();

            predicateList.add(cb.equal(root.get("status").as(Integer.class), Constant.CHECK_STATUS_DEFAULT));

            if (predicateList.size() > 0) {
                result = cb.and(predicateList.toArray(new Predicate[]{}));
            }
            if (result != null) {
                query.where(result);
            }
            return query.getGroupRestriction();
        }, new PageRequest(pageNum - 1, pageSize, Sort.Direction.ASC, "id")).getContent();

        for (Role role : roleList) {
            map = new HashMap<>();
            map.put("id", role.getId());
            map.put("name", role.getName());
            map.put("moduleList", changeList(roleModuleDao.findListByRoleId(role.getId())));
            map.put("masterSize", roleRelationDao.findListByRoleId(role.getId()).size());

            list.add(map);
        }

        BaseVo baseVo = new BaseVo();
        baseVo.setCount(roleDao.findAll().size());
        baseVo.setData(list);

        return baseVo;
    }

    @Override
    public List<Role> findListNoMaster() {
        return roleDao.findListNoMaster();
    }

    private List<Module> changeList(List<RoleModule> roleModuleList) {
        List<Module> list = new ArrayList<>();

        for (RoleModule roleModule : roleModuleList) {
            list.add(roleModule.getModule());
        }

        return list;
    }
}